﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Configuration;
using System.Web;
using System.Xml.Serialization;
using System.Xml;

namespace GtsServer.Common
{
    public class Utils
    {
        #region 获取配置文件中的配置
        /// <summary>
        /// 获取配置文件中的配置
        /// </summary>
        /// <param name="appSettingName"></param>
        /// <returns></returns>
        public static string GetAppSetting(string appSettingName)
        {
            if (ConfigurationManager.AppSettings[appSettingName] == null)
                throw new NullReferenceException(appSettingName +
                                                 " AppSettings value cannot be null or empty in the web.config.");
            return ConfigurationManager.AppSettings[appSettingName];
        }
        #endregion

        #region 将字符串(123,123,334,321)装换成List形式
        /// <summary>
        /// 将字符串(123,123,334,321)装换成List形式
        /// </summary>
        /// <param name="products"></param>
        /// <returns></returns>
        public static List<long> StringToLongList(string ps)
        {
            List<long> pl = new List<long>();
            if (ps == "" || ps == null)
                return pl;
            string[] ss = ps.Split(',');
            for (int i = 0; i < ss.Length; i++)
            {
                pl.Add(Convert.ToInt64(ss[i]));
            }
            return pl;
        }

        public static List<string> StringToStringList(string ps)
        {
            List<string> pl = new List<string>();
            if (ps == "" || ps == null)
                return pl;
            string[] ss = ps.Split(',');
            for (int i = 0; i < ss.Length; i++)
            {
                pl.Add(ss[i]);
            }
            return pl;
        }
        #endregion

        #region 地址处理方法(加上"http://"等)
        /// <summary>
        /// 地址处理方法
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string EditUrl(string url)
        {
            if (url == "" || url == null)
                return url;

            string newUrl = "";
            string setting = GetAppSetting("StaticResourse");
            string[] arry = url.Split(',');
            for (int i = 0; i < arry.Length; i++)
            {
                arry[i] = arry[i].IndexOf("ttp://") > 0 ? arry[i] : setting + arry[i];
                newUrl = newUrl + arry[i] + ",";
            }
            newUrl = newUrl.EndsWith(",") ? newUrl.Remove(newUrl.Length - 1) : newUrl;
            return newUrl;
        }
        /// <summary>
        /// 地址处理方法()
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string EditDomainName(string url)
        {
            if (url == "" || url == null)
                return url;

            string newUrl = "";
            string setting = GetAppSetting("DomainName");
            string[] arry = url.Split(',');
            for (int i = 0; i < arry.Length; i++)
            {
                arry[i] = arry[i].IndexOf("ttp://") > 0 ? arry[i] : setting + arry[i];
                newUrl = newUrl + arry[i] + ",";
            }
            newUrl = newUrl.EndsWith(",") ? newUrl.Remove(newUrl.Length - 1) : newUrl;
            return newUrl;
        }
        #endregion


        /// <summary>
        /// 字符串分割
        /// </summary>
        /// <param name="str"></param>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string[] Split(string str, string s)
        {
            if (str.ToLower().IndexOf(s.ToLower()) < 0)
            {
                string[] tmp = { str };
                return tmp;
            }
            return Regex.Split(str, Regex.Escape(s), RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 截取字符串
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="length">截取长度</param>
        public static string CutString(string str, int length)
        {
            if (str.Length > length)
                return str.Substring(0, length);
            else
                return str;
        }

        /// <summary>
        /// 截取字符串
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="length">截取长度</param>
        /// <param name="appendix">省略号</param>
        public static string CutString(string str, int length, string appendix)
        {
            if (str.Length > length)
                return str.Substring(0, length) + appendix;
            else
                return str;
        }

        #region 字符串相关操作
        #region SimpleUBB(string str) html编码 （转换换行以及空格）
        /// <summary>
        /// html编码 （转换换行以及空格）
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string SimpleUBB(string str)
        {
            return str.Replace("<", "&lt;").Replace(">", "&gt;").Replace("\r\n", "<br />").Replace("  ", " &nbsp;");
        }
        #endregion
        #region LoseHTML(string ) 去除html
        /// <summary>
        /// 去除html
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string LoseHTML(string str)
        {
            if (string.IsNullOrEmpty(str)) { return ""; }
            return Regex.Replace(str, "<\\/*[^<>]*>", "", RegexOptions.IgnoreCase);
        }
        #endregion
        #region clearHtmlAndSpace(string ) 去除html和空格之类的
        /// <summary>
        /// 去除html,多个空格替换成1个
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string clearHtmlAndRSpace(string str)
        {
            if (string.IsNullOrEmpty(str)) { return ""; }
            return Regex.Replace(LoseHTML(str), @"(\s|\&nbsp;)+", " ", RegexOptions.IgnoreCase);
        }
        #endregion
        #region closeHtml(string _str)自动闭合html
        /// <summary>
        /// 自动闭合html
        /// </summary>
        /// <param name="_str"></param>
        /// <returns></returns>
        public static string closeHtml(string _str)
        {
            StringBuilder _newStr = new StringBuilder(_str);
            string[] _array = { "p", "div", "span", "table", "ul", "font", "b", "strong", "u", "i", "h1", "h2", "h3", "h4", "h5", "h6" };
            foreach (string _arrstr in _array)
            {
                System.Collections.Generic.List<int> OpenPosList = new System.Collections.Generic.List<int>();
                Regex re = new Regex(@"\<" + _arrstr + @"( [^\<\>]+|)\>", RegexOptions.IgnoreCase);
                MatchCollection match = re.Matches(_newStr.ToString());
                foreach (Match _match in match)
                    OpenPosList.Add(_match.Index + _match.Length);

                re = new Regex(@"\</" + _arrstr + @"\>", RegexOptions.IgnoreCase);
                match = re.Matches(_newStr.ToString());
                //关闭的标签个数，实际存在的关闭标签个数， 去除的关闭标签个数（跟起始标签对应的，不是真正去除的）
                int ClosePos = 0, ActualClosePos = 0, ClearClosePos = 0;
                for (int i = 0; i < match.Count; i++)
                {
                    if (ActualClosePos < OpenPosList.Count)
                    {
                        if (match[i].Index < OpenPosList[ActualClosePos])
                        {
                            _newStr.Remove(match[i].Index - (ClearClosePos * match[i].Length), match[i].Length);
                            ClearClosePos++;
                        }
                        else ActualClosePos++;
                    }
                    else if (ActualClosePos >= OpenPosList.Count)
                        _newStr.Remove(match[i].Index - ((ClosePos - ActualClosePos) * match[i].Length), match[i].Length);
                    else
                        ActualClosePos++;
                    ClosePos++;
                }
                if (OpenPosList.Count > ActualClosePos)
                    for (int j = 0; j < OpenPosList.Count - ActualClosePos; j++)
                        _newStr.Append("</" + _arrstr + ">");
            }
            return _newStr.ToString();
        }
        #endregion
        #endregion

        #region 字符串与16进制数据之间的转换操作
        /// <summary>
        /// 自定义加密字符串
        /// </summary>
        /// <param name="str">需要加密的字符串</param>
        /// <param name="charset">编码方式</param>
        /// <param name="partition">是否用逗号分隔</param>
        /// <returns></returns>
        public static string EncryptStr(string str, string charset, bool partition)
        {
            if (null != str && "" != str)
            {
                str = str.Replace("\r\n", "");
                str = str.Replace("\n", "");
                str = str.Replace("p", "h4");
                // str = str.Replace(" ", "");
                string strHex = ToHex(str, charset, partition);
                return ToHex16(strHex);
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 自定义解密字符串
        /// </summary>
        /// <param name="str">解密字符串</param>
        /// <param name="charSet">编码方式</param>
        /// <returns></returns>
        public static string DeEncryStr(string str, string charSet)
        {
            string unHex16Str = UnHex16(str); //转为系统的16进制字符
            return UnHex(unHex16Str, charSet);//转为明文
        }
        /// <summary>
        /// 转换为自定义的16位字符
        /// </summary>
        /// <param name="s">16进制的字符串，字符串长度不能少于16位</param>
        public static string ToHex16(string s)
        {
            try
            {
                string str = "1234567GHJKLMNBV";
                string strHex = "0123456789ABCDEF";
                //if (s.Length != 16 || str.Length != 16)
                //    throw new Exception("字符长度必须为16位!");
                char[] cs = str.ToCharArray();
                Dictionary<char, char> dic = new Dictionary<char, char>();
                int i = 0;
                foreach (char c in strHex)
                    dic.Add(c, cs[i++]);

                StringBuilder sb = new StringBuilder();
                foreach (char item in s)
                {
                    if (dic.ContainsKey(item))
                        sb.Append(dic[item]);
                }
                return sb.ToString().Trim();
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// 还原系统16进制字符串
        /// </summary>
        /// <param name="s">需要还原的字符串，字符串长度不能少于16位</param>
        /// <returns></returns>
        public static string UnHex16(string s)
        {
            try
            {
                string str = "1234567GHJKLMNBV";
                string strHex = "0123456789ABCDEF";
                char[] swapChar = strHex.ToCharArray();
                //if (s.Length != 16 || str.Length != 16)
                //    throw new Exception("字符长度必须为16位!");
                Dictionary<char, char> dic = new Dictionary<char, char>();
                int i = 0;
                foreach (char item in str)
                    dic.Add(item, swapChar[i++]);
                StringBuilder sb = new StringBuilder();
                foreach (char c in s)
                {
                    if (dic.ContainsKey(c))
                        sb.Append(dic[c]);
                }
                return sb.ToString();
            }
            catch (Exception e) { throw e; }

        }
        /// <summary>
        /// 将字符串（含中文）转换成16进制数据
        /// </summary>
        /// <param name="s">字符串</param>
        /// <param name="charset">编码格式utf_8,gb2312</param>
        /// <param name="fenge">是否每字符用逗号分隔</param>
        /// <returns></returns>
        public static string ToHex(string s, string charset, bool fenge)
        {
            if ((s.Length % 2) != 0)
            {
                s += " ";//空格
                //throw new ArgumentException("s is not valid chinese string!");
            }
            System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);
            byte[] bytes = chs.GetBytes(s);
            string str = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                str += string.Format("{0:X}", bytes[i]);
                if (fenge && (i != bytes.Length - 1))
                {
                    str += string.Format("{0}", ",");
                }
            }
            return str.ToUpper();
        }

        /// <summary>
        /// 从16进制转换成字符串（含汉字）
        /// </summary>
        /// <param name="hex">16进制数据</param>
        /// <param name="charset">编码,如"utf-8","gb2312"</param>
        /// <returns></returns>
        public static string UnHex(string hex, string charset)
        {
            if (hex == null)
                throw new ArgumentNullException("hex");
            hex = hex.Replace(",", "");
            hex = hex.Replace("\n", "");
            hex = hex.Replace("\\", "");
            hex = hex.Replace(" ", "");
            if (hex.Length % 2 != 0)
            {
                hex += "20";//空格
            }
            // 需要将 hex 转换成 byte 数组。
            byte[] bytes = new byte[hex.Length / 2];

            for (int i = 0; i < bytes.Length; i++)
            {
                try
                {
                    // 每两个字符是一个 byte。
                    bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
                    System.Globalization.NumberStyles.HexNumber);
                }
                catch
                {
                    // Rethrow an exception with custom message.
                    throw new ArgumentException("hex is not a valid hex number!", "hex");
                }
            }
            System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);
            return chs.GetString(bytes);
        }



        #endregion

        #region 文件操作
        #region 返回文件是否存在
        /// <summary>
        /// 返回文件是否存在
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>是否存在</returns>
        public static bool FileExists(string filename)
        {
            return System.IO.File.Exists(filename);
        }
        #endregion
        #region 读取文件
        /// <summary>
        /// 读取文件
        /// </summary>
        /// <param name="_path"></param>
        /// <returns></returns>
        public static string FileRead(string _path)
        {
            if (FileExists(_path))
            {
                try
                {
                    return System.IO.File.ReadAllText(_path, System.Text.Encoding.Default);
                }
                catch { }
            }
            return null;
        }
        #endregion
        #region 写文件
        /// <summary>
        /// 写入文件，如果存在则覆盖
        /// </summary>
        /// <param name="_content"></param>
        /// <param name="_path"></param>
        /// <returns></returns>
        public static bool FileWrite(string _content, string _path)
        {
            return FileWrite(_content, _path, Encoding.UTF8);
        }
        private static object write_Lock = new object();
        /// <summary>
        /// 写入文件，如果存在则覆盖
        /// </summary>
        /// <param name="_content"></param>
        /// <param name="_path"></param>
        /// <returns></returns>
        public static bool FileWrite(string _content, string _path, Encoding code)
        {
            lock (write_Lock)
            {
                StreamWriter sw = null;
                try
                {
                    System.IO.File.WriteAllText(_path, _content, code);
                    sw = new StreamWriter(_path, false, code);
                    sw.Write(_content);
                    sw.Flush();
                    sw.Close();
                    return true;
                }
                catch (Exception ex)
                {
                    return false;
                    throw ex;
                }
                finally
                {
                    if (null != sw)
                        sw.Close();
                }
            }
        }
        #endregion
        #region 删除文件
        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="_path"></param>
        /// <returns></returns>
        public static bool FileDelete(string _path)
        {
            if (FileExists(_path))
            {
                System.IO.File.Delete(_path);
                return true;
            }
            return false;
        }
        #endregion
        #region 获得当前绝对路径
        /// <summary>
        /// 获得当前绝对路径
        /// </summary>
        /// <param name="strPath">指定的路径</param>
        /// <returns>绝对路径</returns>
        public static string GetMapPath(string strPath)
        {
            if (HttpContext.Current != null)
            {
                return HttpContext.Current.Server.MapPath(strPath);
            }
            else //非web程序引用
            {
                return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
            }
        }
        #endregion
        #region 创建目录
        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="_dirpath"></param>
        public static void DirectoryCreate(string _dirpath)
        {
            if (!System.IO.Directory.Exists(_dirpath))
                System.IO.Directory.CreateDirectory(_dirpath);
        }
        #endregion
        #region 删除目录
        /// <summary>
        /// 删除目录
        /// </summary>
        /// <param name="_dirpath"></param>
        public static void DirectoryDelete(string _dirpath)
        {
            if (System.IO.Directory.Exists(_dirpath))
                System.IO.Directory.Delete(_dirpath, true);
        }
        #endregion
        #endregion

        #region GetInArrayID(string, string[], bool)判断指定字符串在指定字符串数组中的位置
        /// <summary>
        /// 判断指定字符串在指定字符串数组中的位置
        /// </summary>
        /// <param name="strSearch">字符串</param>
        /// <param name="stringArray">字符串数组</param>
        /// <param name="caseInsensetive">是否不区分大小写, true为不区分, false为区分</param>
        /// <returns>字符串在指定字符串数组中的位置, 如不存在则返回-1</returns>
        public static int GetInArrayID(string strSearch, string[] stringArray, bool caseInsensetive)
        {
            for (int i = 0; i < stringArray.Length; i++)
            {
                if (caseInsensetive)
                {
                    if (strSearch.ToLower() == stringArray[i].ToLower())
                    {
                        return i;
                    }
                }
                else
                {
                    if (strSearch == stringArray[i])
                    {
                        return i;
                    }
                }

            }
            return -1;
        }
        #endregion

        #region InArray(string , string[] , bool ) 判断指定字符串是否属于指定字符串数组中的一个元素
        /// <summary>
        /// 判断指定字符串是否属于指定字符串数组中的一个元素
        /// </summary>
        /// <param name="strSearch">字符串</param>
        /// <param name="stringArray">字符串数组</param>
        /// <param name="caseInsensetive">是否不区分大小写, true为不区分, false为区分</param>
        /// <returns>判断结果</returns>
        public static bool InArray(string strSearch, string[] stringArray, bool caseInsensetive)
        {
            return GetInArrayID(strSearch, stringArray, caseInsensetive) >= 0;
        }
        #endregion

        #region InArray(string , string[] )判断指定字符串是否属于指定字符串数组中的一个元素
        /// <summary>
        /// 判断指定字符串是否属于指定字符串数组中的一个元素
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="stringarray">字符串数组</param>
        /// <returns>判断结果</returns>
        public static bool InArray(string str, string[] stringarray)
        {
            return InArray(str, stringarray, false);
        }
        #endregion

        #region InArray(string , string , string ) 判断指定字符串是否属于指定字符串数组中的一个元素
        /// <summary>
        /// 判断指定字符串是否属于指定字符串数组中的一个元素
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="stringarray">内部以逗号分割单词的字符串</param>
        /// <param name="strsplit">分割字符串</param>
        /// <returns>判断结果</returns>
        public static bool InArray(string str, string stringarray, string strsplit)
        {
            return InArray(str, Split(stringarray, strsplit), false);
        }
        #endregion


        #region 验证相关

        #region IsIP(string ) 是否为ip
        /// <summary>
        /// 是否为ip
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIP(string ip)
        {
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }
        #endregion

        #endregion

        #region 随机数
        private static string _Random_Int_String = "1234567890";
        private static string _Random_Letter_Lower_String = "abcdefghijklmnopqrstuvwxyz";
        private static string _Random_Letter_Upper_String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        /// <summary>
        /// 产生随机标识 (Guid)
        /// </summary>
        /// <returns></returns>
        public static string Card()
        {
            return (Guid.NewGuid().ToString().Replace("-", "") + Random(4)).ToLower();
        }
        /// <summary>
        /// 产生随机数(给定源字符串)
        /// </summary>
        /// <param name="str">需要产生字符串原始数据</param>
        /// <param name="num">产生的个数</param>
        /// <returns></returns>
        public static string Random(string str, int num, Random rand)
        {
            if (1 > num) { return ""; }
            StringBuilder newstr = new StringBuilder();
            Random rnd;
            if (null == rand)
            {
                long tick = DateTime.Now.Ticks;
                rnd = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
            }
            else
                rnd = rand;
            while (true)
            {
                newstr.Append(str.Substring(rnd.Next(str.Length - 1) + 1, 1));
                if (num == newstr.Length) break;
            }
            return newstr.ToString();
        }
        /// <summary>
        /// 产生随机数，0-9数字和26个字母的随机数
        /// </summary>
        /// <param name="num">随机个数</param>
        /// <returns>0-9数字和26个字母的随机数</returns>
        public static string Random(int num, Random rand)
        {
            return Random(_Random_Int_String + _Random_Letter_Lower_String + _Random_Letter_Upper_String, num, rand);
        }
        public static string Random(int num)
        {
            return Random(num, null);
        }
        #region 可能会删除
        /// <summary>
        /// 产生随机数，0-9数字和26个字母的随机数
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static string randomStr(int num) { return Random(num); }
        /// <summary>
        /// 产生随机数,26个字母
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static string randomString(int num) { return RandomLetter(num); }
        public static string randomCard() { return Card(); }
        //public static string 
        #endregion
        /// <summary>
        /// 产生随机数,0-9数字
        /// </summary>
        /// <param name="num">随机个数</param>
        /// <returns>0-9个数字的随机数</returns>
        public static string RandomInt(int num, Random rand)
        {
            return Random(_Random_Int_String, num, rand);
        }
        public static string RandomInt(int num)
        {
            return RandomInt(num, null);
        }
        /// <summary>
        /// 产生随机数,26个字母
        /// </summary>
        /// <param name="num">随机个数</param>
        /// <param name="rand"></param>
        /// <returns>26个字母的随机数</returns>
        public static string RandomLetter(int num, Random rand)
        {
            return Random(_Random_Letter_Lower_String + _Random_Letter_Upper_String, num, rand);
        }
        /// <summary>
        /// 产生随机数,26个字母
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static string RandomLetter(int num)
        {
            return RandomLetter(num, null);
        }
        #endregion

        #region 加密解密

        #region MD5加密
        /// <summary>
        /// MD5函数
        /// </summary>
        /// <param name="str">原始字符串</param>
        /// <param name="b">true返回大写，false返回小写</param>
        /// <returns></returns>
        public static string Md5(string str, bool isbool)
        {
            return str.Ext_Md5(isbool);
        }
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str">原始字符串</param>
        /// <returns>返回md5加密字符串（小写）</returns>
        public static string Md5(string str)
        {
            return str.Ext_Md5();
        }
        #endregion

        #endregion

        #region 序列化操作
        /// <summary>
        /// 序列化一个Object为String
        /// </summary>
        /// <param name="obj"></param>
        /// <returns>序列化后的字符串</returns>
        public static string Serializer(Object obj)
        {
            try
            {
                XmlSerializer xs = new XmlSerializer(obj.GetType());
                MemoryStream ms = new MemoryStream();
                XmlTextWriter xtw = new XmlTextWriter(ms, System.Text.Encoding.UTF8);
                xtw.Formatting = Formatting.Indented;
                xs.Serialize(xtw, obj);
                ms.Seek(0, SeekOrigin.Begin);
                StreamReader sr = new StreamReader(ms);
                string str = sr.ReadToEnd();
                xtw.Close();
                ms.Close();
                return str;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// 反序列化 从字符串
        /// </summary>
        /// <param name="xml">xml字符串</param>
        /// <param name="type">要生成的对象类型</param>
        /// <returns>反序列化后的对象</returns>
        public static object Deserialize(string str, Type type)
        {
            try
            {
                XmlSerializer xs = new XmlSerializer(type);
                StringReader sr = new StringReader(str);
                object obj = xs.Deserialize(sr);
                return obj;
            }
            catch { return null; }
        }
        #endregion

        #region IP过滤
        public static bool MatchIP(string IP, string FilterIP)
        {
            return MatchIP(IP, FilterIP.Split(','));
        }
        public static bool MatchIP(string IP, string[] FilterIP)
        {
            string[] SplitIP;
            foreach (string _sIP in FilterIP)
            {
                if (!string.IsNullOrEmpty(_sIP))
                {
                    string __sIP = _sIP.Replace("*", " \\d*");
                    SplitIP = __sIP.Split('.');
                    if (4 == SplitIP.Length)
                    {
                        Regex _re = new Regex("(" + SplitIP[0] + ")\\." + "(" + SplitIP[1] + ")\\." + "(" + SplitIP[2] + ")\\." + "(" + SplitIP[3] + ")");
                        MatchCollection matches = _re.Matches(IP);
                        if (0 < matches.Count)
                            return true;
                    }
                }
            }

            return false;
        }
        #endregion

        #region javascript escape编码转化成c#
        public static string Escape(string s)
        {
            StringBuilder sb = new StringBuilder();
            byte[] ba = System.Text.Encoding.Unicode.GetBytes(s);
            for (int i = 0; i < ba.Length; i += 2)
            {
                if (ba[i + 1] == 0)
                {
                    //数字,大小写字母,以及"+-*/._"不变
                    if (
                          (ba[i] >= 48 && ba[i] <= 57)
                        || (ba[i] >= 64 && ba[i] <= 90)
                        || (ba[i] >= 97 && ba[i] <= 122)
                        || (ba[i] == 42 || ba[i] == 43 || ba[i] == 45 || ba[i] == 46 || ba[i] == 47 || ba[i] == 95)
                        )//保持不变
                    {
                        sb.Append(Encoding.Unicode.GetString(ba, i, 2));

                    }
                    else//%xx形式
                    {
                        sb.Append("%");
                        sb.Append(ba[i].ToString("X2"));
                    }
                }
                else
                {
                    sb.Append("%u");
                    sb.Append(ba[i + 1].ToString("X2"));
                    sb.Append(ba[i].ToString("X2"));
                }
            }
            return sb.ToString();

        }
        #endregion
    }
}
